﻿using System;
using System.Windows;
using System.Windows.Input;
using System.Windows.Interop;
using System.Windows.Media;
using System.Windows.Media.Imaging;
using System.Windows.Threading;
using AwesomiumDotNet;

namespace WpfSample
{
    public partial class MainWindow : Window
    {
        PixelFormat pixelFormat = PixelFormats.Rgb24; //PixelFormats.Bgra32;

        WebCore webCore;
        WebView webView;
        DispatcherTimer timer;

        const int WM_KEYDOWN = 0x0100;
        const int WM_KEYUP = 0x0101;
        const int WM_CHAR = 0x0102;

        public MainWindow()
        {
            InitializeComponent();

            webViewImage.MouseMove += webViewImage_MouseMove;
            webViewImage.SizeChanged += webViewImage_SizeChanged;
            webViewImage.MouseDown += webViewImage_MouseDown;
            webViewImage.MouseUp += webViewImage_MouseUp;
            MouseWheel += MainWindow_MouseWheel;

            WebCoreConfig config = new WebCoreConfig();
            config.SetEnablePlugins(true);
            config.SetLogLevel(LogLevel.None);
            webCore = new WebCore(config);

            webView = webCore.CreateWebView((int)Width, (int)Height);
            webView.ChangeCursor += webView_ChangeCursor;
            webView.LoadUrl("http://www.google.com");
            webView.Focus();

            timer = new DispatcherTimer();
            timer.Tick += timer_Tick;
            timer.Start();

            this.SourceInitialized += MainWindow_SourceInitialized;
        }

        void MainWindow_SourceInitialized(object sender, EventArgs e)
        {
            HwndSource source = (HwndSource)PresentationSource.FromVisual(this);
            source.AddHook(HandleMessages);
        }

        IntPtr HandleMessages(IntPtr hwnd, int msg, IntPtr wParam, IntPtr lParam, ref bool handled)
        {
            int message = (msg & 65535); // get low word

            if (message == WM_KEYDOWN || message == WM_KEYUP || message == WM_CHAR)
            {
                webView.InjectKeyboardEvent(new WebKeyboardEvent((uint)msg, (uint)wParam, (int)lParam));
                handled = true;
            }

            return IntPtr.Zero;
        }

        void MainWindow_MouseWheel(object sender, MouseWheelEventArgs e)
        {
            webView.InjectMouseWheel(e.Delta);
        }

        void webViewImage_MouseUp(object sender, MouseButtonEventArgs e)
        {
            webView.InjectMouseUp(AwesomiumDotNet.MouseButton.Left);
        }

        void webViewImage_MouseDown(object sender, MouseButtonEventArgs e)
        {
            webView.InjectMouseDown(AwesomiumDotNet.MouseButton.Left);
        }

        void webView_ChangeCursor(object sender, ChangeCursorEventArgs e)
        {
            Cursor = AwesomiumCursor.GetCursor(e.CursorType);
        }

        void webViewImage_SizeChanged(object sender, SizeChangedEventArgs e)
        {
            webView.Resize((int)e.NewSize.Width, (int)e.NewSize.Height);
        }

        void webViewImage_MouseMove(object sender, MouseEventArgs e)
        {
            Point position = e.GetPosition(null);
            webView.InjectMouseMove((int)position.X, (int)position.Y);
        }

        void timer_Tick(object sender, EventArgs e)
        {
            webCore.Update();
            if (webView.IsDirty)
                Render();
        }

        void Render()
        {
            RenderBuffer buffer = webView.Render();

            int bpp = pixelFormat.BitsPerPixel / 8;
            int stride = buffer.Width * bpp;

            bool convertToRgba = (pixelFormat == PixelFormats.Rgb24);
            byte[] webViewBytes = buffer.Copy(stride, bpp, convertToRgba);

            webViewImage.Source = BitmapSource.Create(buffer.Width, buffer.Height,
                96, 96, pixelFormat, null, webViewBytes, stride);
        }
    }
}
